package com.gmrz.uaf.servlet.v1.handler;

import com.gmrz.uaf.common.Constants;
import com.gmrz.uaf.common.GuiceUtil;
import com.gmrz.uaf.protocol.v1.json.UAFSchemaBuilder;
import com.gmrz.uaf.protocol.v1.processor.UAFDeviceProcessor;
import com.gmrz.uaf.protocol.v1.schema.DeviceDetails;
import com.gmrz.uaf.server.ServerContext;
import com.gmrz.uaf.servlet.v1.request.DeviceListContext;
import com.gmrz.uaf.servlet.v1.request.ReceiveReqPayload;
import com.gmrz.uaf.servlet.v1.response.FidoRespPayload;
import com.gmrz.uaf.servlet.v1.validation.PayloadValidationException;
import com.gmrz.uaf.servlet.v1.validation.RestValidator;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.lang.reflect.Type;
import java.util.List;

/**
 * Created by yangairong on 16/12/28.
 */
public class UAFDeviceListHandler extends UAFBaseHandler{
    private static final Logger LOG = LogManager.getLogger(UAFDeviceListHandler.class);
    /**
     * {
     *     "context":{"transNo":"","userName":"user1","rf1":"","rf2":"","appID":"001"}
     * }
     * @param request
     * @return
     * {
     *     "statusCode":1200,"description":"xxxxxx",
     *     "devices":[
     *     {"userName":"user1","appID":"001","deviceID":"","deviceName":"",.......},
     *     {"userName":"user1","appID":"001","deviceID":"","deviceName":"",.......}
     *     ]
     * }
     */

    public String deviceList(String request){

        LOG.info("[/device/list][begin]");
        ServerContext.getServerContext().getFidoLog().setRequest(request);
        FidoRespPayload<String> respPayload = new FidoRespPayload<String>();
        String response;
        try {
            Gson gson = UAFSchemaBuilder.getGson();
            Type reqType = new TypeToken<ReceiveReqPayload<DeviceListContext>>() {  }
                    .getType();
            ReceiveReqPayload<DeviceListContext> reqPayload =gson.fromJson(request, reqType);
            logRequest(request,reqPayload.getContext().getTransNo(),reqPayload.getContext().getUserName(),
                    reqPayload.getContext().getAppID(), null,null, Constants.Method.DEVICE_LIST);
            validate(reqPayload);

            DeviceListContext context = reqPayload.getContext();
            UAFDeviceProcessor processor = GuiceUtil.getProcessorInjector()
                    .getInstance(UAFDeviceProcessor.class);
            String userName = generateHashedUserName(context.getUserName(),context.getRf1(),context.getRf2());
            List<DeviceDetails> devices = processor.list(userName,context.getAppID());

            respPayload.setStatusCode(1200);
            respPayload.setDescription("OK");
            respPayload.setDevices(devices);
            return gson.toJson(respPayload);
        }catch (Exception ex){
            LOG.error(ex);
            response = buildFidoRespFromException(respPayload,ex);
        }
        LOG.info("[/device/list][end]");
        return response;
    }

    private void validate(ReceiveReqPayload<DeviceListContext> reqPayload)
            throws PayloadValidationException
    {
        if ((reqPayload == null) || (reqPayload.getContext() == null)) {
            throw new PayloadValidationException("context", RestValidator.VALIDATION_ERROR.EMPTY);
        }
        String appID = reqPayload.getContext().getAppID();
        String userName = reqPayload.getContext().getUserName();
        RestValidator.validate("appID", appID);
        RestValidator.validate("userName", userName);
        RestValidator.validate("transNo",reqPayload.getContext().getTransNo());

        RestValidator.validate("rf1", reqPayload.getContext().getRf1());
        RestValidator.validate("rf2", reqPayload.getContext().getRf2());
    }

}
